﻿#include<iostream>
#include<thread>
#include<mutex>
#include<queue>
#include<condition_variable>
#include<chrono>
using namespace std;
/*
condition_variable（条件变量）是C++标准库中用于多线程同步的重要工具
为了​​实现线程间的有条件等待与通知机制​​
解决了单纯使用互斥锁时无法高效实现的“等待特定条件成立”的场景

比如生产者消费者模型：
生产者生向任务队列里加入任务，并通知消费者去做任务
消费者从任务队列里取任务，任务做完停止
*/
queue<int> q;
extern mutex mtx;
std::condition_variable g_cv;

void producer() {
	for (int i = 1; i <= 15; i++) {
		unique_lock<mutex> lock(mtx);
		q.push(i);
		q.push(i * 16);
		cout << "!!!生产者生产任务：" << i << " " << i * 16 << endl;

		lock.unlock();//解锁
		g_cv.notify_one();//通知一个线程

		std::this_thread::sleep_for(std::chrono::milliseconds(300));
	}
}

void consumer() {
	while (true) {
		unique_lock<mutex> lock(mtx);
		//wait函数会解锁互斥锁，并等待条件变量被通知,然后判断条件是否为真，真则继续执行
		//当条件为false时，wait函数会解锁互斥锁，并等待条件变量被通知
		g_cv.wait(lock, [] {return !q.empty(); });
		cout << "***消费者消费任务：" << q.front() << endl;
		q.pop();
	}
}

int main7() {
	thread t1(producer);  //线程运行
	thread t2(consumer);  //线程运行
	//上面这两个线性是并发的
	t1.join();
	t2.join();

	//thread(producer).join();  //创建线性运行并阻塞
	//thread(consumer).join();  //等待阻塞结束再创建线程并阻塞
	/*
	这个输出结果跟上面完全不一样，这个不是并发的！

	因为​​线程在创建时就已经开始运行
	而join和detach只是主线程中用来管理线程对象的“限制符”或操作
	*/

	return 0;
}